import re


# 整个自定义的bed类对象和相应的Exception
class BedFormatError(Exception):                                # 自定义的exception
    def __init__(self, col):
        Exception.__init__(self)
        self.__col = col

    def __str__(self):
        def errorMessage(col):
            return {
                'start': 'start是否是int？',
                'end': 'end是否是int？',
                'score': 'score是否是int?',
                'strand': 'strand： + or - or .',
            }[col]

        return repr(errorMessage(self.__col))


class bed:
    def __init__(self, chromosome, start, end, name, score, strand):
        self.setChromosome(chromosome)
        self.setStart(start)
        self.setEnd(end)
        self.setName(name)
        self.setScroe(score)
        self.setStrand(strand)

    def __gt__(self, other):  # 自定义的比较大小的两个类，用于后期的sort
        if self.chromosome > other.chromosome:
            return True
        elif self.chromosome == other.chromosome:
            if self.start > other.start:
                return True
        else:
            return False

    def __lt__(self, other):
        if self.chromosome < other.chromosome:
            return True
        elif self.chromosome == other.chromosome:
            if self.start < other.start:
                return True
        else:
            return False

    def __and__(self, other):                                                   # 正常使用的两个类的&，用来判断这两个类是不是具有重叠位点
        strn = re.compile(r'[.]')                                               # 方便多了，只需要遍历一边就行了，不想java需要写的比较麻烦
        results = False
        if self.chromosome == other.chromosome:                                 # 判断是不是相同染色体
            if not (strn.match(self.strand) and strn.match(other.strand)):      # 判断链是不是. 以此分开判断
                if self.strand == other.strand:                                 # 判断是不是相同链
                    if self.end >= other.start and self.start <= other.end:     # 判断两者是不是具有重合位点
                        results = True
            else:
                if self.end >= other.start and self.start <= other.end:
                    results = True
        return results

    # 自定义的setters和getters
    def getChromosome(self):
        return self.chromosome

    def getStart(self):
        return self.start

    def getEnd(self):
        return self.end

    def getName(self):
        return self.name

    def getScore(self):
        return self.score

    def getStrand(self):
        return self.strand

    def setChromosome(self, chromosome):
        self.chromosome = chromosome

    def setStart(self, start):
        if not isinstance(start, int):
            raise BedFormatError('start')
        else:
            self.start = start

    def setEnd(self, end):
        if not isinstance(end, int):
            raise BedFormatError('end')
        else:
            self.end = end

    def setName(self, name):
        self.name = name

    def setScroe(self, score):
        if not isinstance(score, int):
            raise BedFormatError('score')
        else:
            self.score = score

    def setStrand(self, strand):
        checkStrand = re.compile(r'[.+-]')
        if not checkStrand.match(strand):
            raise BedFormatError('strand')
        else:
            self.strand = strand

    def getAll(self):
        return self.chromosome + "\t" + str(self.start) + "\t" + str(self.end) + "\t" + self.name\
               + "\t" + str(self.score) + "\t" + self.strand
